﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using EzDesk.Core.Data;
using EzDesk.Core.Model;
using EzDesk.Core.Interface;
using EzDesk.Utility.Log;

namespace EzDesk.Core.ServiceImpl.Services
{
    public partial class CoreService : ICoreService
    {
        public CoreService()
        {
            LogEx.TRACE("CoreService - CoreService", "初始化CoreService");
        }


        #region [ private methods ]

        private ICoreService self
        {
            get
            {
                return (ICoreService)this;
            }
        }


        private Guid[] convertSingleIdToIdCollection(Guid singleId)
        {
            Guid[] guids = new Guid[1]
            {
                singleId
            };
            return guids;
        }

        private Guid[] convertIdStrsToIdCollection(string idStrs)
        {
            var idStrList = idStrs.Split(',');

            IList<Guid> idList = new List<Guid>();

            foreach (var idStr in idStrList)
            {
                Guid result;
                if (Guid.TryParse(idStr, out result))
                {
                    idList.Add(result);
                }
            }
            return idList.ToArray();
        }

        #endregion


        UserProfile ICoreService.GetUserProfileByUserName(string userName)
        {
            return EzDeskDatabaseContainer.Go(
                container => container.UserProfileSet.FirstOrDefault(p => p.UserCode == userName).ExtendModel(container));
        }

        UserProfile ICoreService.GetUserProfileById(Guid userId)
        {
            return EzDeskDatabaseContainer.Go(
                container => container.UserProfileSet.FirstOrDefault(p => p.Id == userId).ExtendModel(container));
        }

        UserProfile ICoreService.CreateEmptyUserProfile(string userName)
        {
            var userProfile =
                new UserProfile()
                    {
                        Id = Guid.NewGuid(),
                        UserCode = userName,
                    };
            EzDeskDatabaseContainer.GoAndSave(
                container => container.UserProfileSet.AddObject(userProfile));
            return userProfile;
        }

        void ICoreService.DeleteUserProfile(Guid userId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {
                        var userProfile = container.UserProfileSet.FirstOrDefault(p => p.Id == userId);
                        if (userProfile != null)
                        {
                            container.UserProfileSet.DeleteObject(userProfile);
                        }
                    });
        }

        IList<UserProfile> ICoreService.GetUserProfiles(Guid[] userIdCollection)
        {
            return EzDeskDatabaseContainer.Go(
                container => userIdCollection
                    .Select(userId => container.UserProfileSet.FirstOrDefault(p => p.Id == userId))
                    .Where(userProfile => userProfile != null)
                    .ToList()
                    .Select(p => p.ExtendModel(container)).ToList()
                    );
        }


        IList<UserProfile> ICoreService.GetUserProfiles(string memberstring)
        {
            Guid[] userIds =
                self.GetAllUsersByMemberString(memberstring)
                .Select(p => p.Id)
                .ToArray();

            return self.GetUserProfiles(userIds);
        }

        SimpleUser ICoreService.GetSimpleUserById(Guid userId)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                    {
                        var userProfile = container.UserProfileSet.FirstOrDefault(p => p.Id == userId);
                        return userProfile.ToSimpleUser(container);
                    });
        }




        IList<SimpleUser> ICoreService.GetSimpleUserInfos(Guid[] userIdCollection)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                    {
                        var userProfiles = userIdCollection
                            .Select(userId => container.UserProfileSet.FirstOrDefault(p => p.Id == userId))
                            .Where(userProfile => userProfile != null)
                            .ToList();
                        return userProfiles
                            .Select(userProfile => userProfile.ToSimpleUser(container))
                            .ToList();
                    });
        }

        IList<SimpleUser> ICoreService.GetSimpleUserInfos(string memberstring)
        {
            Guid[] userIdsToSent =
                self.GetAllUsersByMemberString(memberstring)
                .Select(p => p.Id)
                .ToArray();

            return self.GetSimpleUserInfos(userIdsToSent);
        }

        SimpleUser ICoreService.GetSimpleUserInfoByUserName(string userName)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                    {
                        var userProfile = container.UserProfileSet.FirstOrDefault(p => p.UserCode == userName);
                        SimpleUser simpleUser = null;
                        if (userProfile != null)
                        {
                            simpleUser = userProfile.ToSimpleUser(container);
                        }
                        return simpleUser;
                    });
        }

        IList<SimpleUser> ICoreService.GetUsersInDept(Guid deptId)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                container.UserProfileSet
                    .Where(p => p.DeptId == deptId)
                    .ToList()
                    .Select(p => p.ToSimpleUser(container))
                    .ToList()
                );
        }

        IList<Dept> ICoreService.GetAllDepts()
        {
            return EzDeskDatabaseContainer.Go(
                container => container.DeptSet.ToList());
        }

        Dept ICoreService.GetDeptById(Guid deptId)
        {
            return EzDeskDatabaseContainer.Go(
                container => container.DeptSet.FirstOrDefault(p => p.Id == deptId)
                );

        }

        Dept ICoreService.CreateDept(string deptName)
        {
            return EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {

                        //判断名字不重复
                        var dept = container.DeptSet.FirstOrDefault(p => p.DeptName == deptName);
                        if (dept != null)
                        {
                            throw new Exception("Duplicated Dept Name");
                        }

                        //创建相应分组
                        var newGroup = self.CreateGroup(null, null, deptName, 1 /* GroupType = 1 部门组 */);

                        // 创建新的Dept 写入
                        var newDept = new Dept()
                                          {
                                              Id = new Guid(),
                                              DeptName = deptName,
                                              GroupId = newGroup.Id,
                                          };

                        container.DeptSet.AddObject(newDept);
                        return newDept;
                    });
        }
        void ICoreService.DeleteDept(Guid deptId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {
                        var dept = container.DeptSet.FirstOrDefault(p => p.Id == deptId);
                        var group = container.GroupSet.FirstOrDefault(p => p.Id == dept.GroupId);

                        container.GroupSet.DeleteObject(group);
                        container.DeptSet.DeleteObject(dept);
                    });
        }
        void ICoreService.ChangeUserDept(Guid userId, Guid deptId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {
                        var dept = container.DeptSet.FirstOrDefault(p => p.Id == deptId);
                        if (dept == null)
                        {
                            throw new Exception("Dept not found!!!");
                        }

                        // 从当前部门删除
                        self.RemoveUserFromCurrentDept(userId);

                        // 添加入新的部门
                        var userProfile = container.UserProfileSet.FirstOrDefault(p => p.Id == userId);
                        userProfile.DeptId = deptId;
                        container.SaveChanges();

                        // 将用户加入到对应的Group
                        self.AddUserInGroup(dept.GroupId.GetValueOrDefault(Guid.Empty), userId);
                    });
        }

        void ICoreService.ChangeUserPosition(Guid userId, Guid positionId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {
                        // todo: validate Position Id

                        var userProfile = container.UserProfileSet.FirstOrDefault(p => p.Id == userId);
                        userProfile.PositionId = positionId;
                    });
        }

        IList<SimpleUser> ICoreService.GetUsersInPosition(Guid posId)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                container.UserProfileSet
                    .Where(p => p.PositionId == posId)
                    .ToList()
                    .Select(p => p.ToSimpleUser(container))
                    .ToList()
                );
        }

        void ICoreService.RemoveUserFromCurrentDept(Guid userId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {
                        var userProfile = container.UserProfileSet.FirstOrDefault(p => p.Id == userId);
                        container.LoadProperty(userProfile, p=>p.Dept);
                        
                        if (userProfile.Dept != null)
                        {
                            var dept = userProfile.Dept;
                            self.RemoveUserFromGroup(dept.GroupId.GetValueOrDefault(Guid.Empty), userProfile.Id);
                            userProfile.DeptId = null;
                        }
                    });
        }

        void ICoreService.ChangeDeptName(Guid deptId, string deptName)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {
                        var dept = container.DeptSet.FirstOrDefault(p => p.Id == deptId);
                        var group = container.GroupSet.FirstOrDefault(p => p.Id == dept.GroupId);

                        group.Description = deptName;
                        dept.DeptName = deptName;
                    });
        }


        IList<Position> ICoreService.GetPositions()
        {
            return EzDeskDatabaseContainer.Go(
                container => container.PositionSet.ToList());
        }

        Position ICoreService.CreatePosition(string descrition, int priority)
        {
            var position = new Position()
            {
                Id = Guid.NewGuid(),
                Description = descrition,
                Priority = priority,
            };
            EzDeskDatabaseContainer.GoAndSave(
                container => container.PositionSet.AddObject(position));
            return position;
        }

        void ICoreService.ChangePositionPriority(Guid positionId, int priority)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {
                        var position = container.PositionSet.FirstOrDefault(p => p.Id == positionId);
                        position.Priority = priority;
                    });
        }

        void ICoreService.ChangePositionDescription(Guid positionId, string description)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var position = container.PositionSet.FirstOrDefault(p => p.Id == positionId);
                    position.Description = description;
                });
        }

        void ICoreService.DeletePosition(Guid positionId)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var position = container.PositionSet.FirstOrDefault(p => p.Id == positionId);
                    container.PositionSet.DeleteObject(position);
                });
        }



        FeedTemplate ICoreService.CreateFeedTemplate(string titleTemplate, string bodyTemplate, int type)
        {
            throw new NotImplementedException();
        }

        void ICoreService.DeleteFeedTemplate(Guid id)
        {
            throw new NotImplementedException();
        }

        FeedTemplate ICoreService.GetFeedTemplateById(Guid templateId)
        {
            return EzDeskDatabaseContainer.Go(
                container => container.FeedTemplateSet.FirstOrDefault(p => p.Id == templateId));
        }

        IList<FeedTemplate> ICoreService.GetFeedTemplate(string templateName)
        {
            throw new NotImplementedException();
        }





        public void UpdateHeadIcon(Guid userId, byte[] iconData, string imageType)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                {
                    var userProfile = container.UserProfileSet.FirstOrDefault(p => p.Id == userId);
                    container.LoadProperty(userProfile, p => p.UserHeadImage);
                    if (userProfile.UserHeadImage != null)
                    {
                        container.UserHeadImageSet.DeleteObject(userProfile.UserHeadImage);
                        container.SaveChanges();
                    }
                    var newUserHeadImage =
                        new UserHeadImage()
                            {
                                Id = Guid.NewGuid(),
                                ImageData = iconData,
                                ImageType = imageType,
                                UpdateOn = DateTime.Now,
                            };
                    userProfile.UserHeadImage = newUserHeadImage;
                });
        }

        public UserHeadImage GetHeadIcon(Guid userId)
        {
            return EzDeskDatabaseContainer.Go(
                container =>
                    {
                        var userProfile = container.UserProfileSet.FirstOrDefault(p => p.Id == userId);
                        container.LoadProperty(userProfile, p => p.UserHeadImage);
                        return userProfile.UserHeadImage;
                    });
        }




        public void UpdateUserProfile(UserProfile userProfile)
        {
            EzDeskDatabaseContainer.GoAndSave(
                container =>
                    {
                        container.UserProfileSet.Attach(userProfile);
                        container.ObjectStateManager.ChangeObjectState(userProfile, EntityState.Modified);
                    });
        }
    }
}
